feat(diagnostics): surface twd-js failure diagnostics in the run summary - #20
Merged
Conversation
A failing test now reports which mock rules never fired, above the error
message:
mock rules 6/7 triggered — catalog never requested
AssertionError: expected 0 rows (at http://localhost:5173/cg-1/...)
Above the error, not below, because a twd-js failure message can carry a
full accessible-roles dump that would bury it.
The planned approach needed twd-js to expose its formatter on `window` so
the in-page `onFail` could reach it — new public surface on the library,
and a blocking decision. That is not necessary: the snapshot is plain
data, so `onFail` carries `test.diagnostics` out with the result entry and
rendering happens in Node.
Better split regardless. This package already owns its terminal style and
shares no rendering with twd-js — a divergence the upstream sidebar
removal confirms is deliberate. The stable contract between the two is the
data shape, not the rendering. It also puts the snapshot in the run report
as structured data, so shard artifacts and anything reading run.json get
it too, not just the terminal.
Only the mock-rule signal is rendered. The snapshot's `location` row is
dropped: every failure message here already ends in `(at <href>)`, and the
full href is strictly more informative than pathname + search + hash.
Printing both would say the same thing twice.
No schema bump. `diagnostics` is additive and optional on tests[];
runReport spreads it through and mergeReports carries it across the merge
without either knowing about it.
Verified beyond the mocked suite: the in-page onFail is driven against a
stub runner, since page.evaluate is mocked everywhere else and would never
otherwise execute it. Output is byte-identical to before when no snapshot
is present, and a real failing test against the shipped twd-js 1.9.0
prints exactly as it always has, exit code 1.
twd-js has not released diagnostics yet (PR #335 open), so the populated
path is unit-tested only and degrades to today's output until it ships.
456 tests pass, coverage 96.13% -> 97.08%.
TWD Contract Validation
23 passed · 41 failed · 3 warnings · 1 skipped Failed validations./contracts/users-3.0.json
./contracts/posts-3.1.json
./contracts/products-3.0.json
./contracts/events-3.1.json
|
This was referenced Sep 6, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A failing test now reports which mock rules never fired, above the error message:
Above the error, not below, for upstream's reason: a twd-js failure message can carry a full accessible-roles dump that would bury the block.
Consumes the snapshot added by BRIKEV/twd#335.
Needs no change to twd-js
NEXT-DIAGNOSTICS.mdplanned to render the block inside the page, which required twd-js to expose its formatter aswindow.__twdFormatDiagnostics— new public surface on the library's engine entry, and a blocking maintainer decision.That turned out to be unnecessary. The snapshot is plain data, so the in-page
onFailjust carriestest.diagnosticsout with the result entry and rendering happens in Node.It's the better split regardless:
c46b17econfirms the two surfaces are diverging on purpose.run.jsonget it too — not just the terminal.The
locationrow is deliberately droppedThis resolves the open question in
NEXT-DIAGNOSTICS.md. Every failure message here already ends in(at <href>), and the full href is strictly more informative than the snapshot's pathname + search + hash. Printing both would say the same thing twice, so the CLI keeps the href and renders only what it did not already have.No schema bump
diagnosticsis additive and optional ontests[].runReport.jsspreads it through andmergeReports.jscarries it across the merge without either knowing about it. Bumping would make an additive field needlessly loud, given the version guard is already exact-match.Safe to merge before the twd-js release
Output is byte-identical to today when no snapshot is present, which is exactly what shipped twd-js 1.9.0 sends. The block simply appears once diagnostics land on npm.
Verification
Unit:
untriggeredarray.onFailis driven against a stub runner.page.evaluateis mocked everywhere else, so this callback would otherwise never execute in the suite.errorintact.Live, against a real browser:
mainafter #335, built and installed from a local pack: the populated path renders for real — single-alias row, multi-alias list, and no row at all for a test that registered no rules.456 tests pass (was 439). Coverage 96.13% → 97.08%.
Upstream caveat found while verifying — twd-js, not this package
collectDiagnostics()readsgetRequestMockRules(), the global rule registry, with no per-test scoping. Nothing in twd-js resets it between tests;twd.clearRequestMockRules()is public but calling it is up to the app.So in an app that does not clear rules in an
afterEach, aliases accumulate across the run and each failing test is blamed for every rule registered before it. Three failing tests in onetest-example-apprun:The third registers zero mocks. Run in isolation it correctly prints no row, which confirms the rendering is right and the input is not.
Worth fixing in twd-js before release — it inverts the feature, pointing at four aliases unrelated to the failure. Nothing to change here: twd-cli renders faithfully whatever the snapshot contains.
🤖 Generated with Claude Code